package com.onpositive.mediawiki.serializing;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;

import com.onpositive.data.IPropertyConstants;
import com.onpositive.data.IPropertyMetadata;
import com.onpositive.data.serializer.writers.AbstractWriter;
import com.onpositive.data.serializer.writers.IWriterFactory;
import com.onpositive.units.ParsedDate;
import com.onpositive.units.ParsedDimension;
import com.onpositive.units.ParsedFileList;
import com.onpositive.units.ParsedIdent;
import com.onpositive.units.ParsedLinkArray;
import com.onpositive.units.ParsedScalar;
import com.onpositive.units.ParsedString;
import com.onpositive.units.ParsedValueSequenceV2;
import com.onpositive.units.TextContent;
 

public class WriterFactory implements IWriterFactory {
	
	private static HashMap<String,Constructor<? extends AbstractWriter<?>>> writerConstructorMap = new HashMap<String, Constructor<? extends AbstractWriter<?>>>() ;
	
	static{
		try {
			writerConstructorMap.put( ParsedDimension.ID 	  , ScalarValueWriter.class.getConstructor()  ) ;
			writerConstructorMap.put( ParsedScalar.ID    	  , ScalarValueWriter.class.getConstructor()  ) ;
			writerConstructorMap.put( ParsedDate.ID 	 	  , DateValueWriter.class.getConstructor()    ) ;
			writerConstructorMap.put( ParsedIdent.ID	 	  , ValueSequenceWriter.class.getConstructor()) ;
			//writerConstructorMap.put( ParsedIdent.ID	 	  , IdentWriter.class.getConstructor()			 ) ;
			writerConstructorMap.put( ParsedString.ID	 	  , StringValueWriter.class.getConstructor()     ) ;
			writerConstructorMap.put( TextContent.ID 	  	  , TextContentWriter.class.getConstructor()	 ) ;
			writerConstructorMap.put( ParsedLinkArray.ID	  , LinkArrayWriter.class.getConstructor()		 ) ;
			writerConstructorMap.put( ParsedFileList.ID  	  , FileListWriter.class.getConstructor()		 ) ;
			writerConstructorMap.put( ParsedValueSequenceV2.ID, ValueSequenceWriter.class.getConstructor()) ;
			
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
	}
	     
	
	
	@SuppressWarnings("rawtypes")
	private HashMap<IPropertyMetadata,AbstractWriter> writerMap = new HashMap<IPropertyMetadata, AbstractWriter>() ;

	@Override
	public AbstractWriter<?> createWriter(IPropertyMetadata meta) {
		
//		if( ! (meta instanceof ParsedPropertyMetadata) )
//			return null ;
		
		@SuppressWarnings("rawtypes")
		AbstractWriter result = writerMap.get(meta);
		
		if( result == null )
		{
			if( meta instanceof IDefineWriterMetadata )
				return ((IDefineWriterMetadata)meta).getWriter() ;

			String id = (String) meta.getMetaPropertyValue( IPropertyConstants.CHAR_PARSER_ID_LABEL );			
			
			Constructor<?> constructor = writerConstructorMap.get(id) ;
			if( constructor == null )
				return null ;

			try {				
				result = (AbstractWriter<?>) constructor.newInstance();
				writerMap.put( meta, result ) ;		
				
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		
		return result ;
	}

}
